/*热点管理模块：对服务器上备份的文件进行检测，哪些文件长时间没有被访问，则认为是非热点文件，进行压缩存储，节省空间
    1.遍历所有文件，检测文件最后一次访问的时间，与当前时间进行相减
        有两种方案：
            1）从数据管理模块中遍历所有的备份文件信息
            2）遍历备份文件夹，获取所有文件进行属性获取
        选择第二种：
            遍历备份文件夹，每次获取文件的最新数据进行判断，并且还可以解决数据信息缺漏的问题

    2.对非热点文件进行压缩处理，并删除原文件
    3.修改数据管理模块对应的文件信息（压缩标志->true)
*/

#pragma once

#include <iostream>
#include <string>
#include <stdlib.h>
#include <unistd.h>

#include "data.hpp"

extern cloud::DataManager *_data;

namespace cloud
{
    class HotManager
    {
    private:
        std::string _back_dir;
        std::string _pack_dir;
        std::string _pack_suffix;
        int _hot_time;

    private:
        // 非热点文件返回真
        bool HotJudge(const std::string &filename)
        {
            FileUtil fu(filename);
            time_t last_atime = fu.LastATime();
            time_t cur_time = time(NULL);
            if (cur_time - last_atime > _hot_time)
            {
                return true;
            }
            return false;
        }

    public:
        HotManager()
        {
            Config *config = Config::GetInstance();

            _back_dir = config->GetBackDir();
            _pack_dir = config->GetPackDir();
            _pack_suffix = config->GetPackFileSuffix();
            _hot_time = config->GetHotTime();

            //如果目录不存在，就创建目录，否则在下面调用ScanDirectory时，目录不存在就会报错
            FileUtil tmp1(_back_dir);
            FileUtil tmp2(_pack_dir);
            tmp1.CreateDirectory();
            tmp2.CreateDirectory();
        }

        bool RunModule()
        {
            while (1)
            {
                // 遍历备份文件，获取所有文件名
                FileUtil fu(_back_dir);
                std::vector<std::string> arry;
                fu.ScanDirectory(&arry);

                // 遍历判断文件是否是非热点文件
                for (auto &a : arry)
                {
                    // 热点文件不需要处理
                    if (HotJudge(a) == false)
                        continue;

                    // 获取文件的备份信息
                    BackupInfo bi;
                    if (_data->GetOneByRealpath(a, &bi) == false)
                    {
                        // 现在有一个文件存在，但是没有备份信息
                        // 设置一个备份信息
                        bi.NewBackupInfo(a);
                    }

                    // 对文件进行压缩
                    FileUtil tmp(a);
                    tmp.Compress(bi.pack_path);

                    // 删除源文件信息
                    tmp.Remove();

                    bi.pack_flag = true;
                    _data->Updata(bi);
                }
                usleep(1000);  //避免空目录循环遍历，消耗CPU资源过高
            }
            return true;
        }
    };

}